using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using DeathReportManagement.Data;
using DeathReportManagement.Models;

namespace DeathReportManagement.Services;

public class AuthService
{
    private readonly DeathReportContext _context;
    private readonly IHttpContextAccessor _httpContextAccessor;
    
    public AuthService(DeathReportContext context, IHttpContextAccessor httpContextAccessor)
    {
        _context = context;
        _httpContextAccessor = httpContextAccessor;
    }
    
    public async Task<User?> AuthenticateDoctorAsync(string doctorCode)
    {
        var user = await _context.Users
            .FirstOrDefaultAsync(u => u.DoctorCode == doctorCode && u.IsActive && u.Role == "Doctor");
        
        if (user != null)
        {
            await SignInUserAsync(user);
        }
        
        return user;
    }
    
    public async Task<User?> AuthenticateAdminAsync(string doctorCode, string password)
    {
        var user = await _context.Users
            .FirstOrDefaultAsync(u => u.DoctorCode == doctorCode && 
                                    u.Password == password && 
                                    u.IsActive && 
                                    u.Role == "Admin");
        
        if (user != null)
        {
            await SignInUserAsync(user);
        }
        
        return user;
    }
    
    private async Task SignInUserAsync(User user)
    {
        var claims = new List<Claim>
        {
            new(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new(ClaimTypes.Name, user.Name),
            new("DoctorCode", user.DoctorCode),
            new(ClaimTypes.Role, user.Role),
            new("Department", user.Department ?? "")
        };
        
        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
        
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext != null)
        {
            await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);
        }
    }
    
    public async Task SignOutAsync()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext != null)
        {
            await httpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
    
    public User? GetCurrentUser()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext?.User?.Identity?.IsAuthenticated == true)
        {
            var userIdClaim = httpContext.User.FindFirst(ClaimTypes.NameIdentifier);
            if (userIdClaim != null && int.TryParse(userIdClaim.Value, out int userId))
            {
                return _context.Users.FirstOrDefault(u => u.Id == userId);
            }
        }
        return null;
    }
    
    public int? GetCurrentUserId()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext?.User?.Identity?.IsAuthenticated == true)
        {
            var userIdClaim = httpContext.User.FindFirst(ClaimTypes.NameIdentifier);
            if (userIdClaim != null && int.TryParse(userIdClaim.Value, out int userId))
            {
                return userId;
            }
        }
        return null;
    }
    
    public bool IsAdmin()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        return httpContext?.User?.IsInRole("Admin") == true;
    }
    
    public bool IsDoctor()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        return httpContext?.User?.IsInRole("Doctor") == true;
    }
}